home *** CD-ROM | disk | FTP | other *** search
- /*
- ╔════════════════════════════════════════╗
- ║ UDISK ║
- ║ Copyright (c) 1996 L.I.Williams ║
- ║ All rights reserved ║
- ║ Issue 1.0 Date: 13Jul96 ║
- ╚════════════════════════════════════════╝
- *~ UDISK.C
- *~ 08Jul96 Iss 1.0 Created by LIW
- *~ Reports disk size, space used and free
- *~ Use CL /AT /W4 UDISK.C to compile this file
- *~
- */
- /***********************************************************************
- * HISTORY:
- * Date Iss Who Comment
- * 08Jul96 1.0 LIW Created
- ***********************************************************************/
- /* Include files: */
- #include <stdio.h>
- #include <dos.h>
- #include <string.h>
- #include <process.h>
- #include <stdlib.h>
- #include <setjmp.h>
-
- /* global variables */
- char error_handler[4] = { 0xb8, 0, 0, 0xcf };
- union REGS iregs, oregs;
- struct SREGS segregs;
-
- /* prototypes */
- void print_size(long);
- void drv_info(int);
- void explain(void);
-
- /***********************************************************************
- * main sorts out error handling and calls drv_info for each drive
- ***********************************************************************/
- void main(int argc, char *argv[])
- {
- int drives;
- unsigned int olderr_offset, olderr_segment;
- int i;
-
- /* initialize for error handling */
- iregs.x.ax = 0x3524; /* get error handler vector */
- intdosx(&iregs, &oregs, &segregs);
- olderr_offset = oregs.x.bx;
- olderr_segment= segregs.es;
-
- segread(&segregs); /* pick up segment registers */
- iregs.x.ax = 0x2524; /* set our error handler vector */
- iregs.x.dx = (unsigned int)error_handler;
- intdosx(&iregs, &oregs, &segregs);
-
- /* sort out command */
- if (argc > 1)
- {
- explain();
- exit(1);
- }
-
- /* determine number of logical drives in system */
- iregs.h.ah = 0x19; /* get current disk */
- intdos(&iregs, &oregs);
- iregs.h.dl = oregs.h.al;
- iregs.h.ah = 0x0e; /* select disk */
- intdos(&iregs, &oregs);
- drives = oregs.h.al;
- /* this is the number of drives set by lastdrive, default 5 */
-
- printf ("\nUDISK 1.0, Freeware, (c) 1996 L. I. Williams.\n");
- printf ("\n Disk Usage Information\n\n");
- printf("Drive Volume Total Space Used Space Free Space Used%% Free%%\n\n");
-
- /* now output drive info */
- for (i = 0; i < drives; i++)
- drv_info(i);
-
- printf("\
- \n\
- /? for help. (1k=1000 not 1024 1m=1,000,000 not 1,048,576)\n\
- ");
-
- /* restore vector for error handling */
- iregs.x.ax = 0x2524; /* get error handler vector */
- oregs.x.dx = olderr_offset;
- segregs.ds = olderr_segment;
- intdosx(&iregs, &oregs, &segregs);
- exit(0);
- }
-
- /***********************************************************************
- drv_info. Information for each drive if present
- ***********************************************************************/
- void drv_info(int drive)
- {
- long total, free, used;
- double percent;
- struct find_t find;
- int found;
- char *p;
- int i;
- char spec[20];
- char ch;
- struct diskfree_t drvinfo;
-
- /*
- Try to print the statistics. When a non-existant drive is read the
- operating system calls its fatal error handler (via INT 24h). This
- has been redirected and returns, this routine returns too, and the
- drive is skipped.
- */
- if (_dos_getdiskfree( drive+1, &drvinfo )!=0)
- return;
-
- total = (long)drvinfo.total_clusters *
- (long)drvinfo.sectors_per_cluster *
- (long)drvinfo.bytes_per_sector;
-
- free = (long)drvinfo.avail_clusters *
- (long)drvinfo.sectors_per_cluster *
- (long)drvinfo.bytes_per_sector;
-
- used = total - free;
-
- /* Output disk letter. numeric 0 = drive A */
- printf(" %c: ", drive + 'A');
-
- /* Scan files in root directory of disk for one with volume id
- attribute. It's name is the disk label. Find first matching file,
- then find additional matches. */
- sprintf(spec,"%c:\\*.*",drive + 'A'); /* pathname of root */
- found = !_dos_findfirst( spec, 0xffff, &find ); /* first file name */
- while (found)
- {
- if ( find.attrib & _A_VOLID ) /* is it the volume id ? */
- break; /* yes, leave loop */
- found = !_dos_findnext( &find ); /* no, try another */
- }
- *spec = '\0'; /* preset null string */
- if (found) /* did we get it ? */
- {
- p = spec; /* yes, copy name, ommiting '.' character */
- for (i=0;i<=14;i++)
- {
- ch = find.name[i];
- if (ch != '.')
- *p++=ch; /* copy non '.' characters */
- if (ch == '\0') /* stop after null */
- break;
- }
- }
-
- printf( "%-13s",spec); /* output name or null to 13 spaces */
-
- print_size(total);
-
- print_size(used);
-
- print_size(free);
-
- percent = (double)used / (double)total * 100.0;
- printf(" %5.0f%% ", percent);
-
- percent = (double)free / (double)total * 100.0;
- printf("%5.0f%%\n", percent);
-
- /* Try to deal with CDROM, network drives etc. This does not work if
- there is no CD in the drive, so commented out.
- iregs.h.ah = 0x44; determine if unusual drive
- iregs.h.al = 0x09;
- iregs.h.bl = drive +1;
- intdos(&iregs,&oregs);
- if (oregs.x.dx & 0x1000)
- {
- sprintf(spec,"vol %c:",drive + 'A');
- system(spec);
- printf("\n");
- }
- */
- }
-
- /***********************************************************************
- prints a disk size in a sensible way
- ***********************************************************************/
- void print_size(long n)
- {
- if (n >= 10000000) /* 10m or more */
- printf("%7.0fm ",(double)n/1000000.0);
- else if (n >= 1000000) /* 1m to 10m */
- printf("%7.1fm ",(double)n/1000000.0);
- else if (n >= 10000) /* 10k to 999k */
- printf("%7.0fk ",(double)n/1000);
- else /* < 10k */
- printf("%7ld ",n);
- printf(" ");
- }
-
- /***********************************************************************
- Help output
- ***********************************************************************/
- void explain(void)
- {
- char filebuf[80];
-
- _searchenv( "MORE.COM", "PATH", filebuf );
- if (*filebuf)
- {
- _searchenv( "UDISK.DOC", "PATH", filebuf );
- if (*filebuf)
- {
- system("type UDISK.DOC | more");
- exit(0);
- }
- }
- printf("See the documentation file 'UDISK.DOC' for more information.\n");
- }
- /***********************************************************************
- End of code
- ***********************************************************************/
-